#include "Base.h"

#include <unistd.h>
#include <stdlib.h>

int decode_step (unsigned char current_step, unsigned char * result) {

  if (result == NULL)
    return -1;

  if ((current_step & (1 << 6))) {
    result[2] = 0xFF;

    return -1;
  }
  
  int x, y, valid = 0;

  for (x = 0; x < 3; x++) {

    if (current_step & (0x1 << x)) {
      if (valid)
        return -1;
      else
        break;
    }
  }

  valid = 0;

  for (y = 3; y < 6; y++) {
    if (current_step & (0x1 << y)) {
      if (valid)
        return -1;
      else
        break;
    }
  }

  result[0] = x;
  result[1] = y - 3;
  if (current_step & (0x1 << 7))
    result[2] = 'x';
  else
    result[2] = 'o';

  return 0;
}

int encode_step (unsigned char * current_step, unsigned char * res) {

  if (current_step == NULL || res == NULL)
    return -1;

  unsigned char result = * res;
  result = 0x0;

  if (current_step[2] == 0xFF)
    result = 0x1 << 6;

  int i;
  for (i = 0; i < 2; i++)
    // Such magic need because in "human" notaion [0][0] will be [1][1].
    current_step[i] -= ('0' + 1);

  if (current_step[1] > 3 || current_step[0] > 3)
    result = (1 << 7 | 1 << 6);

  if (result) {
    * res = result;
    return -1;
  }

  result |= 0x1 << current_step[0];
  result |= 0x1 << (current_step[1] + 3);
  if (current_step[2] == 'x')
      result |= 0x1 << 7;
  else if (current_step[2] == 'o')
      result &= ~(0x1 << 7);
  else
    result = (1 << 7 | 1 << 6);

  * res = result;

  return 0;
}

int send_to (int fifo_fd, unsigned char step) {

  if (fifo_fd < 1)
    return -1;

  return  write (fifo_fd, &step, sizeof(char));
}

int receive_from (int fifo_fd, unsigned char * current_step) {
  if ((fifo_fd < 1) || (current_step == NULL))
    return -1;

  return read (fifo_fd, current_step, sizeof(char));
}
